package com.tool.emulator.apple2.ui;

import java.awt.*;
import java.awt.event.AWTEventListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.MouseWheelEvent;

/**
 * ZoomFont.java @author tl 2011-6-11
 */
public class ZoomFont extends Font {
	public static final float min_rate = 0.5f;
	public static final float rate_factor = 1.05f;
	public static final float max_rate = 4f;
	public static volatile float current_rate = 1.0f;

	static {
		Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
			public void mouseWheelMoved(MouseWheelEvent e) {
				if (e.isControlDown() && (e.getSource() instanceof Frame) || (e.getSource() instanceof Dialog)) {
					if (e.getWheelRotation() < 0) {
						zoomIn((Component) e.getSource());
					} else if (e.getWheelRotation() > 0) {
						zoomOut((Component) e.getSource());
					}
					if (e.getSource() instanceof Dialog)
						((Dialog) e.getSource()).pack();
				}
			}

			public void eventDispatched(AWTEvent event) {
				if (event instanceof MouseWheelEvent) {
					mouseWheelMoved((MouseWheelEvent) event);
					return;
				}

				if (!(event instanceof HierarchyEvent))
					return;
				HierarchyEvent he = (HierarchyEvent) event;
				if (he.getChangeFlags() != HierarchyEvent.DISPLAYABILITY_CHANGED)
					return;
				zoomComponents((Component) event.getSource(), current_rate);
				if (event.getSource() instanceof Dialog) {
					((Dialog) event.getSource()).pack();
				}
			}

		}, HierarchyEvent.HIERARCHY_EVENT_MASK | MouseWheelEvent.MOUSE_WHEEL_EVENT_MASK);
	}

	public final Font orgFont;
	public final float rate;

	public ZoomFont(Font orgFont, float rate) {
		super(orgFont.getName(), orgFont.getStyle(), (int) (0.5 + orgFont.getSize() * rate));
		this.orgFont = orgFont;
		this.rate = rate;
	}

	public static void zoom(Component c, float rate) {
		Font font = c.getFont();
		if (font != null) {
			if (font instanceof ZoomFont)
				font = ((ZoomFont) font).zoom(rate);
			else
				font = new ZoomFont(font, rate);
			if (font != null)
				c.setFont(font);
		}
	}

	public static void zoomComponents(Component c, float rate) {
		if (c == null) return;
		if (rate < min_rate) rate = min_rate;
		if (rate > max_rate) rate = max_rate;
		current_rate = rate;
		zoomComponents0(c, rate);
	}

	private static void zoomComponents0(Component c, float rate) {
		zoom(c, rate);
		if (c instanceof Container) {
			for (Component c1 : ((Container) c).getComponents()) {
				zoomComponents0(c1, rate);
			}
		}
	}

	public static void zoomIn(Component c) {
		zoomComponents(c, current_rate * rate_factor);
	}

	public static void zoomOut(Component c) {
		zoomComponents(c, current_rate / rate_factor);
	}

	public static void initializ(Component c) {
		zoomComponents(c, current_rate);
	}

	private ZoomFont zoom(float rate) {
		if (rate == this.rate)
			return null;
		return new ZoomFont(this.orgFont, rate);
	}

}
